package yf.mall.service.impl;

import com.aliyuncs.utils.IOUtils;
import com.yf.utils.DateUtil;
import org.springframework.beans.factory.annotation.Value;
import yf.mall.common.Const;
import yf.mall.dao.*;
import yf.mall.entity.*;
import com.yf.entity.TokenEntity;
import com.yf.entity.WxUser;
import com.yf.service.impl.BaseServiceImpl;
import yf.mall.enums.*;
import com.yf.response.RRException;
import com.yf.service.TokenService;
import com.yf.service.WxWebService;
import yf.mall.service.*;
import yf.mall.vo.UserEntityVo;
import yf.mall.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

/**
 * 用户Service实现类
 *
 * @author hxf
 * @email 505860922@qq.com
 * @date Tue Aug 27 18:12:02 CST 2019
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<UserEntity> implements UserService {

    private UserDao userDao;

    @Autowired
    private WxWebService wxWebService;

    @Autowired
    private TokenService tokenService;


    @Autowired
    public void setDao(UserDao userDao) {
        this.userDao = userDao;
        super.setBaseDao(userDao);
    }


    /**
     * 内部方法
     **/

    private void updateTeam(UserEntity user, UserEntity topUser) {
        String oldTeam = user.getTeam();
        String newTeam = user.getId() + "/";
        //设置Team
        if (topUser.getTeam() != null) {
            newTeam = topUser.getTeam() + newTeam;
        } else {
            newTeam = "/" + newTeam;
        }
//        user.setTeam(newTeam);
        userDao.update(user);
        //更新下面团队的前缀
        if (oldTeam != null) {
            String oldTCode = user.getTCode();
            String newTCode = oldTCode;
            if (topUser.getTCode() != null) {
                newTCode = topUser.getTCode();
            }
            userDao.updateTeam(oldTCode, newTCode, oldTeam, newTeam);
        }
    }


    /**
     * 外部方法实现
     **/

    @Override
    public List<UserVo> queryListVo(UserVo userVo) {
        return userDao.queryListVo(userVo);
    }

    @Override
    public UserVo getVo(Long id) {
        return userDao.getVo(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVo updateVo(UserVo userVo) {
        //验证手机号码
        validatePhone(userVo.getUser().getMobile(), userVo.getUser());
        //判断上级
        LevelEntity newLevel = this.levelDao.get(userVo.getUser().getLevelId());
//        updateExp(userVo.getUser().getId(),newLevel);
        String topUserCode = userVo.getTopUser().getCode();
        if (topUserCode == null) {
            throw new RRException("请填写上级");
        }
        UserEntity topUser = userDao.findByCode(topUserCode);
        if (topUser == null) {
            throw new RRException("上级编号无效!");
        }
        userVo.getUser().setPid(topUser.getId());
        //判断推荐人
        String refererCode = userVo.getReferer().getCode();
        if (refererCode != null) {
            UserEntity referer = userDao.findByCode(refererCode);
            if (referer != null) {
                if (referer.equals(userVo.getUser().getRid())) {
                    userVo.getUser().setRid(Const.ADMIN_ID);
                } else {
                    userVo.getUser().setRid(referer.getId());
                }
            }
        }
        //更新用户基本信息
        update(userVo.getUser());
        //更新树
        updateTeam(userVo.getUser(), topUser);
        return userVo;
    }

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private LevelRecordService levelRecordService;

//    @Override
//    public void updateExp(Long userId, LevelEntity newLevel) {
//        LevelEntity oldlevel = this.levelDao.findByUserId(userId);
//        newLevel = this.levelDao.get(newLevel.getId());
//        if (oldlevel.getId() != newLevel.getId()) {
//            LevelRecordEntity record = new LevelRecordEntity();
//            record.setOldLevel(oldlevel.getName());
//            record.setNowLevel(newLevel.getName());
//            record.setUserId(userId);
//            record.setTime(new Date());
//            this.levelRecordService.save(record);
//            AccountEntity account = this.accountDao.findByUserIdAndType(userId, AccountTypeEnum.EXP.getIndex());
//            if (account != null) {
//                account.setAmount(newLevel.getAmount());
//                this.accountDao.update(account);
//            } else {
//                AccountEntity accountEntity = new AccountEntity();
//                accountEntity.setUserId(userId);
//                accountEntity.setType(AccountTypeEnum.EXP.getIndex());
//                accountEntity.setAmount(newLevel.getAmount());
//                this.accountDao.save(accountEntity);
//            }
//        }
//    }


    @Override
    public UserEntity findByCode(String code) {
        return userDao.findByCode(code);
    }

    @Override
    public UserEntity findByMobile(String mobile) {
        return userDao.findByMobile(mobile);
    }

    @Override
    public List<UserEntity> findByVip(String tCode) {
        return userDao.findByVip(tCode);
    }

    @Override
    public void validateUser(UserEntity fromUser, UserEntity toUser) {
        //验证账户
        String fromUserName = fromUser.getName();
        String fromUserCode = fromUser.getCode();
//        if (fromUserCode == null || fromUserCode.trim().equals("")) {
//            throw new RRException("请填写转货人信息!");
//        }
        if (fromUserCode != null && !fromUserCode.trim().equals("")) {
            fromUser = userDao.findByCode(fromUserCode);
            if (fromUser == null || !fromUser.getName().equals(fromUserName)) {
                throw new RRException("转货人信息不匹配!");
            }
        }
        String toUserName = toUser.getName();
        String toUserCode = toUser.getCode();
        if (toUserCode == null || toUserCode.trim().equals("")) {
            throw new RRException("请填写接收人信息!");
        }
        toUser = userDao.findByCode(toUserCode);
        if (toUser == null || !toUser.getName().equals(toUserName)) {
            throw new RRException("接收人信息不匹配!");
        }

    }

    @Override
    public List<UserVo> findByNameOrCodeOrMobile(String param) {
        return userDao.findByNameOrCodeOrMobile(param);
    }



    @Override
    public List<UserVo> findByTop(Long userId, Integer type) {
        List<UserVo> results = new ArrayList<>();

        List<UserVo> userVos = this.userDao.findByUserId(userId);


        results.addAll(userVos);
        // 递归查找下级
        if (type != null) {
            findByList(results, userVos, type);
        }
        return results;
    }


    private void findByList(List<UserVo> results, List<UserVo> userVos, int type) {
        if (userVos.size() > 0 && type != 0) {
            List<UserVo> tems = userDao.findList(userVos);
            results.addAll(tems);
            type = type - 1;
            findByList(results, tems, type);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TokenEntity wxLogin(WxUser wxUser, Long topUserId, Boolean register) {
        TokenEntity tokenEntity;

        //判断用户是否存在
        String wxId = wxUser.getOpenId();
        UserEntity userEntity = userDao.findByWxId(wxId);

//        if (userEntity != null) {
//            String code = "zmz135251zmz294094zmz141996zmz232949zmz416701zmz269794zmz257506zmz198622";
//            if (!code.contains(userEntity.getCode())) {
//                throw new RRException("系统升级中，请稍后重试");
//            }
//        }
        //更新unionId
        if (wxUser.getUnionId() != null && !wxUser.getUnionId().equals("")) {
            UserEntity tem = userDao.findByWxId(wxUser.getUnionId());
            if (userEntity != null && tem == null) { //unionid后面录入
                userEntity.setUnionId(wxUser.getUnionId());
            } else {
                userEntity = tem;
            }
        }


        //用户不存在
        if (userEntity == null) {
            //如果可以注册直接注册
            if (register) {
                userEntity = register(wxUser.getOpenId(), wxUser.getUnionId(), wxUser.getNickName(), wxUser.getHeadImgUrl(), null, null, topUserId);
            } else {
                return null;
            }
        } else {
            //只有没有设置名称的时候更新名称
            if (userEntity.getName() == null || userEntity.getName().equals("")) {
                userEntity.setName(wxUser.getNickName());
            }
            //没有绑定手机号 重新绑定上级 不能绑定公司
            if (userEntity.getMobile() == null && topUserId != null&&!topUserId.equals(Const.ADMIN_ID)) {
                UserEntity topUser = userDao.get(topUserId);
                if (topUser != null) {
                    if (topUserId.equals(userEntity.getId())) {
                        userEntity.setPid(Const.ADMIN_ID);
                    } else {
                        userEntity.setPid(topUserId);
                        userEntity.setRid(topUserId);
                        updateTeam(userEntity, topUser);
                    }
                }
            }
            userEntity.setUnionId(wxUser.getUnionId());
            userEntity.setOpenId(wxUser.getOpenId());
            userEntity.setAvatar(wxUser.getHeadImgUrl());
            userDao.update(userEntity);
        }
        tokenEntity = tokenService.createToken(userEntity.getId());
        return tokenEntity;
    }

    //TODO 验证验证码
    @Override
    public TokenEntity phoneLogin(String avatar, String name, String openId, String unionId, String phone, String captcha, Long topUserId, Boolean register) {
        UserEntity userEntity = userDao.findByMobile(phone);
        if (userEntity == null) {
            //如果不可以注册
            if (!register) {
                return null;
            }
            //直接注册
            userEntity = register(openId, unionId, name, avatar, phone, captcha, topUserId);
        } else {
            //只有没有设置名称的时候更新名称
            if (userEntity.getName() == null || userEntity.getName().equals("")) {
                userEntity.setName(name);
            }
            userEntity.setAvatar(avatar);
            userDao.update(userEntity);
        }
        TokenEntity tokenEntity = tokenService.createToken(userEntity.getId());
        return tokenEntity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserEntity register(String openId, String unionId, String name, String avatar, String phone, String captcha, Long topUserId) {
/*        if (topUserId == null) {//不存在上家  上家设置为
            topUserId = Const.ADMIN_ID;
        }*/

        //上级是公司or为null 则不让注册
        if(topUserId == null){
            throw new RRException("失败:请扫推荐人的二维码进入");
        }
        if (topUserId.equals(Const.ADMIN_ID)){
            throw new RRException("失败:请扫推荐人的二维码进入");
        }
        UserEntity topUser = get(topUserId);
        if (topUser == null) {
            throw new RRException("推荐人不存在!");
        }
//        LevelEntity levelEntity = levelDao.findBase();
        UserEntity userEntity = new UserEntity(phone, openId, unionId, avatar, name, createCode(topUser.getTCode()), topUser.getTCode(), topUser.getId(), topUser.getId(), null, null, new Date(), UserStatusEnum.ACTIVE.getIndex());
        save(userEntity);
        levelService.initBaseLevel(userEntity.getId());
        updateTeam(userEntity, topUser);
        //通知
        noticeService.sendUserIn(topUser.getOpenId(), userEntity.getName(), "");
        return userEntity;
    }

    @Autowired
    private LevelService levelService;

    @Autowired
    AccountService accountService;

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public UserEntity wgRegister(String unionId, String name, String code, String tCode, String avatar, String phone, Long topUserId, String topCode) {
//        UserEntity userEntity = null;
//        if (topCode == null || ("").equals(topCode)) {
//            return null;
//        }
//        //查找上级
//        UserEntity topUser = userDao.findByCode(topCode);
//        if (null == topUser) {
//            return null;
//        }
//        topUserId = topUser.getId();
//        LevelEntity levelEntity = levelDao.findBase();
//        if (unionId != null) {
//            userEntity = userDao.findByWxId(unionId);
//            if (null == userEntity) {
//                userEntity = new UserEntity(phone, null, unionId, avatar, name, code, tCode, topUserId, topUserId, null, levelEntity.getId(), new Date(), UserStatusEnum.ACTIVE.getIndex());
//                save(userEntity);
//                accountService.rewardWgRegister(userEntity.getId());
//            }
//        }
//        return userEntity;
//    }


    @Override
    public UserEntity register(String openId, Long topUserId) {
        WxUser wxUser = wxWebService.getWxUserBySdk(openId);
        //判断用户是否存在
        String wxId = wxUser.getOpenId();
        UserEntity userEntity = userDao.findByWxId(wxId);
        //更新unionId
        if (wxUser.getUnionId() != null && !wxUser.getUnionId().equals("")) {
            UserEntity tem = userDao.findByWxId(wxUser.getUnionId());
            if (userEntity != null && tem == null) { //unionid后面录入
                userEntity.setUnionId(wxUser.getUnionId());
            } else {
                userEntity = tem;
            }
        }
        if (userEntity != null) {
            userEntity.setOpenId(wxUser.getOpenId());
            userEntity.setUnionId(wxUser.getUnionId());
            update(userEntity);
            return userEntity;
        }
        //如果不存在则注册
        userEntity = register(openId, wxUser.getUnionId(), wxUser.getNickName(), wxUser.getHeadImgUrl(), null, null, topUserId);
        return userEntity;
    }

    @Autowired
    private NoticeService noticeService;

    public static void main(String[] args) {
        System.out.println((int)Math.ceil(111111+Math.random()*888888));
//        System.out.println(System.currentTimeMillis());
    }

    @Autowired
    private LevelDao levelDao;

    private String createCode(String tCode) {
        String code = tCode + (int)Math.ceil(111111+Math.random()*888888);
        int count = 0;
        while (findByCode(code) != null) {
            count++;
            code = tCode + (int)Math.ceil(111111+Math.random()*888888);
            if (count > 5) {
                throw new RRException("生成代理失败");
            }
        }
        return code;
    }


    //团队
    private void createTeam(UserEntity userEntity, UserEntity topUser) {
        String team = userEntity.getTeam() + topUser.getId() + "/";
        userEntity.setTeam(team);
        update(userEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserEntity update(Long userId, String phone, String password, String name, Boolean async,String topPhone) {
        UserEntity userEntity = userDao.get(userId);
        Boolean canReward = false;
        //首次完善信息才送
        if(userEntity.getMobile()==null||"".equals(userEntity.getMobile())||userEntity.getMobile().equals("null")){
            canReward = true;
        }
        if (async == null || !async) {
            userEntity.setPassword(password);
            userEntity.setName(name);
            validatePhone(phone, userEntity);
            userEntity.setMobile(phone);
            //修改上级
            if (topPhone != null && !"".equals(topPhone)){
                UserEntity topUser = userDao.findByMobile(topPhone);
                if (topUser == null){
                    throw new RRException("系统不存在该手机号");
                }
                userEntity.setPid(topUser.getId());
                userEntity.setRid(topUser.getId());
            }
            userDao.update(userEntity);
            if(canReward){
                accountService.rewardRegister(userId);
            }
            return userEntity;
        } else {//同步账号  后期去掉 TODO 就是切换账号
            if (userEntity.getMobile() != null && !userEntity.getMobile().equals("")) {
//                throw new RRException("请勿重复同步!");
                return userEntity;
            }

            UserEntity tem = userDao.findByMobile(phone);
            if (tem == null) {
                throw new RRException("手机号码不存在!");
            }

            if (tem.getOpenId() != null && !tem.getOpenId().equals("")) {
                throw new RRException("账号已被同步!");
            }

            tem.setAvatar(userEntity.getAvatar());
            tem.setName(userEntity.getName());
            tem.setUnionId(userEntity.getUnionId());
            tem.setOpenId(userEntity.getOpenId());
            userDao.update(tem);
            userEntity.setOpenId("");
            userEntity.setUnionId("");
            userDao.update(userEntity);//直接删除
            return tem;
        }


    }

    @Override
    public void validatePhone(String phone, UserEntity userEntity) {
        try {
            UserEntity tem = userDao.findByMobile(phone);
            if (tem != null && userEntity != null && !tem.getId().equals(userEntity.getId())) {
                throw new RRException("手机号码已经被占用!");
            }
            if (tem != null && userEntity == null) {
                throw new RRException("手机号码已经被占用");
            }
        } catch (Exception e) {
            throw new RRException("手机号码已经被占用!");
        }
    }

    @Override
    public void validateUser(Long userId) {
        UserEntity userEntity = userDao.get(userId);
        if (userEntity.getStatus() != null && userEntity.getStatus().equals(UserStatusEnum.BAN.getIndex())) {
            throw new RRException("已禁止操作");
        }
    }

    @Override
    public UserEntity getLvTopUser(Long userId,String auth) {
        UserEntity userEntity = get(userId);
        if (userEntity == null) {
            throw new RRException("用户:" + userId + "不存在");
        }
        LevelEntity userLv = levelService.findByUserId(userId,auth);
        UserEntity topUser = get(userEntity.getPid());
        int num = 0;
        while (topUser != null) {
            num++;
            if (num > 30) {
                throw new RRException("层级关系错误,请联系管理员");
            }
            LevelEntity topLv = levelService.findByUserId(topUser.getId(),auth);
            //上级是公司或者高级别用户
            if (topUser.getId().equals(Const.ADMIN_ID) || topLv.getLv() < userLv.getLv()) {
                break;
            }
            topUser = get(topUser.getPid());
        }
        return topUser;
    }

    @Override
    public UserEntity findByWxId(String wxId) {
        return userDao.findByWxId(wxId);
    }

    @Autowired
    private AccountRecordDao accountRecordDao;

//    /**
//     * 查询当前用户信息并查询当前用户的总粉丝数，总代理数，总佣金
//     *
//     * @param userId
//     * @return
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public UserEntityVo findNowUserInfo(Long userId) {
//        UserEntityVo userEntityVo = new UserEntityVo();
//        UserEntity userEntity = this.userDao.get(userId);
//        userEntityVo.setUserEntity(userEntity);
////        Long lv = this.levelDao.findBase().getId();
////      获取粉丝数
//        // 获取总粉丝数
//        List<UserEntity> userEntities = this.userDao.findByTop(userId);
//        List<UserEntity> results = new ArrayList<>();
//        List<UserEntity> userEntityList = new ArrayList<>();
//
//
//        results.addAll(userEntities);
//        results = findByLists(results, userEntities);
//
//        for (UserEntity result : results) {
//            if (result.getLevelId() == lv) {
////                System.out.println(result.getName()+result.getLevelId());
//                continue;
//            }
//            userEntityList.add(result);
//        }
//        userEntityVo.setAgentNum(userEntityList.size());
//        userEntityVo.setFansNum(results.size() - userEntityList.size());
//
//        //TODO
//        BigDecimal totalShareDone = this.accountRecordDao.total(Const.ADMIN_ID, userId, AccountTypeEnum.CASH.getIndex(), AccountRecordStatusEnum.DONE.getIndex(), null, AccountRecordBusEnum.SHARE_REWARD.getIndex());
//        BigDecimal totalAreaDone = this.accountRecordDao.total(Const.ADMIN_ID, userId, AccountTypeEnum.CASH.getIndex(), AccountRecordStatusEnum.DONE.getIndex(), null, AccountRecordBusEnum.AREA_REWARD.getIndex());
//        BigDecimal totalShareWait = this.accountRecordDao.total(Const.ADMIN_ID, userId, AccountTypeEnum.CASH.getIndex(), AccountRecordStatusEnum.WAIT.getIndex(), null, AccountRecordBusEnum.SHARE_REWARD.getIndex());
//        BigDecimal totalAreaWait = this.accountRecordDao.total(Const.ADMIN_ID, userId, AccountTypeEnum.CASH.getIndex(), AccountRecordStatusEnum.WAIT.getIndex(), null, AccountRecordBusEnum.AREA_REWARD.getIndex());
//        BigDecimal bigDecimal = this.accountRecordDao.totalByInfo(Const.ADMIN_ID, userId, AccountTypeEnum.CASH.getIndex(), AccountRecordStatusEnum.DONE.getIndex(), AccountRecordBusEnum.TRANSFER.getIndex(), "%" + Const.REWARD_TRANSFER + "%");
//        BigDecimal decimal = this.accountRecordDao.totalByInfo(Const.ADMIN_ID, userId, AccountTypeEnum.CASH.getIndex(), AccountRecordStatusEnum.WAIT.getIndex(), AccountRecordBusEnum.TRANSFER.getIndex(), "%" + Const.REWARD_TRANSFER + "%");
//        if (bigDecimal == null) {
//            bigDecimal = BigDecimal.ZERO;
//        }
//        if (decimal == null) {
//            decimal = BigDecimal.ZERO;
//        }
//        if (totalShareDone == null) {
//            totalShareDone = BigDecimal.ZERO;
//        }
//
//        if (totalShareWait == null) {
//            totalShareWait = BigDecimal.ZERO;
//        }
//
//        if (totalAreaDone == null) {
//            totalAreaDone = BigDecimal.ZERO;
//        }
//        if (totalAreaWait == null) {
//            totalAreaWait = BigDecimal.ZERO;
//        }
//        totalShareDone = totalShareDone.add(bigDecimal);
//        totalShareDone = totalShareDone.add(totalAreaDone);
//        totalShareWait = totalShareWait.add(decimal);
//        totalShareWait = totalShareWait.add(totalAreaWait);
//        BigDecimal backDone = this.accountRecordDao.total(userId, Const.ADMIN_ID, AccountTypeEnum.CASH.getIndex(), AccountRecordStatusEnum.DONE.getIndex(), Const.REWARD_TRANSFER, AccountRecordBusEnum.BACK.getIndex());
//        if (backDone != null) {
//            totalShareDone = totalShareWait.subtract(backDone);
//        }
//
//
//        userEntityVo.setTotalDone(totalShareDone);
//        userEntityVo.setTotalWait(totalShareWait);
//        return userEntityVo;
//    }

    @Override
    public UserEntity findLeader(Long userId) {
        UserEntity user = get(userId);
        UserEntity parent = null;
        int index = 0;
        while (!user.getId().equals(Const.ADMIN_ID)){
            LevelEntity levelEntity = levelDao.get(user.getLevelId());
            //找到领导人 包括自己
            if(levelEntity.getName().equals("联盟单位.")){
                parent = user;
                break;
            }
            user = userDao.get(user.getPid());
            index++;
            if(index>50){
                throw new RRException("上下级关系有误");
            }
        }
        return parent;
    }

    private List<UserEntity> findByLists(List<UserEntity> results, List<UserEntity> userEntities) {
        if (userEntities.size() > 0) {
            List<UserEntity> tems = userDao.findByList(userEntities);
            results.addAll(tems);
            findByLists(results, tems);
        }
        return results;
    }

    @Autowired
    private AreaDao areaDao;

    @Value("${AUTH-IMG}")
    private String authImg;

    @Override
    public void createAuthImg(Long userId, HttpServletResponse response,String auth) {
        UserEntity userEntity = get(userId);
        try {
            URL url = new URL(authImg);
            BufferedInputStream inputStream = new BufferedInputStream(url.openStream());
            BufferedImage bufferedImage = ImageIO.read(inputStream);
            Graphics g = bufferedImage.getGraphics();
            g.setColor(Color.BLACK);
            g.setFont(new Font("宋体", Font.BOLD, 30));
            //名字
            g.drawString(userEntity.getName(), 420, 625);
            //手机号
            g.drawString(userEntity.getMobile(), 420, 700);
            //区域代理 TODO 搜索区域代理
            List<AreaEntity> areaEntityList = this.areaDao.findByUserId(userEntity.getId());
            if (!areaEntityList.isEmpty()) {

                g.drawString(areaEntityList.get(0).getName() + "区域代理", 420, 866);

            }//编号
            g.drawString(userEntity.getCode(), 420, 950);
            //级别
            LevelEntity levelEntity = levelService.findByUserId(userId,auth);
            g.drawString(levelEntity.getName(), 420, 1026);
            //时间
            g.drawString(DateUtil.dateFormat("yyyy-MM-dd", userEntity.getTime()), 290, 1135);
            g.dispose();
            ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
            IOUtils.closeQuietly(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
